package com.wizz.trade.trading.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wizz.trade.common.PageVo;
import com.wizz.trade.information.entity.Bankinfo;
import com.wizz.trade.information.mapper.*;
import com.wizz.trade.trading.dto.ConsRequestDto;
import com.wizz.trade.trading.dto.TradeRequestDto;
import com.wizz.trade.trading.dto.page.RequestPageDto;
import com.wizz.trade.trading.entity.Cons;
import com.wizz.trade.trading.entity.Request;
import com.wizz.trade.trading.entity.Trade;
import com.wizz.trade.trading.mapper.ConsMapper;
import com.wizz.trade.trading.mapper.RequestMapper;
import com.wizz.trade.trading.mapper.TradeMapper;
import com.wizz.trade.trading.service.RequestService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wizz.trade.trading.vo.StampDutyRequestVo;
import com.wizz.trade.trading.vo.TradeRequestVo;
import com.wizz.trade.trading.vo.basic.RequestVo;
import com.wizz.trade.util.FileOperationUtil;
import com.wizz.trade.util.PageUtil;
import com.wizz.trade.util.SeqIdGenerator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 付款申请表 服务实现类
 * </p>
 *
 * @author fyftless
 * @since 2023-07-25 08:15:51
 */
@Service
public class RequestServiceImpl extends ServiceImpl<RequestMapper, Request> implements RequestService {

    @Resource
    private ConsMapper consMapper;

    @Resource
    private SeqIdGenerator seqIdGenerator;

    @Resource
    private RequestMapper requestMapper;

    @Resource
    private CompanyMapper companyMapper;

    @Resource
    private CompanydeptMapper companydeptMapper;

    @Resource
    private BankinfoMapper bankinfoMapper;

    @Resource
    private CurrencyMapper currencyMapper;

    @Resource
    private TradeMapper tradeMapper;

    @Resource
    private FileOperationUtil fileOperationUtil;

    @Resource
    private MoneytypeMapper moneytypeMapper;

    @Override
    public void addRequestByConsIds(ConsRequestDto consRequestDto) {
        Request request = new Request();
        //设置日期
        request.setDate(consRequestDto.getDate());
        //款项、款项类别
        request.setType(consRequestDto.getType());
        request.setMoney(consRequestDto.getMoney());
        //设置关联信息
        Integer firstIdOfCons = consRequestDto.getConsList().get(0);
        Cons cons = consMapper.selectById(firstIdOfCons);
        request.setLedger(cons.getLedger());
        request.setOurDept(cons.getOurDept());
        request.setCurrency(cons.getCurrency());
        //设置银行信息
        request.setBank(consRequestDto.getBank());
        //设置金额
        request.setAmount(consRequestDto.getAmount());
        request.setPaid(consRequestDto.getPaid());
        //设置申请单号,REQ+款项+款项明细+账套+部门+6日期+3序号
        StringBuilder sb = new StringBuilder();
        sb.append("REQ");
        sb.append(request.getMoney());
        sb.append(request.getType());
        sb.append(String.format("%02d", request.getLedger()));
        sb.append(String.format("%02d", request.getOurDept()));
        sb.append(request.getDate().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        String prefix = sb.toString();
        String seqId = seqIdGenerator.generateAutoIncreaseSeqId(prefix, 3);
        request.setRequestNo(prefix + seqId);
        //设置其余属性
        request.setNote(consRequestDto.getNote());
        request.setTaxAuthority(consRequestDto.getTaxAuthority());
        //同步对应的合同记录的requestNo字段
        for (Integer conId : consRequestDto.getConsList()) {
            Cons cons1 = new Cons();
            cons1.setRequestno(request.getRequestNo());
            cons1.setId(conId);
            consMapper.updateById(cons1);
        }
        requestMapper.insert(request);
    }

    @Override
    public void addRequestByTradeIds(TradeRequestDto tradeRequestDto) {
        //最大申请单数
        final int maxSize = 5;

        Request request = new Request();
        //设置日期
        request.setDate(tradeRequestDto.getDate());
        //款项、款项类别
        request.setType(tradeRequestDto.getType());
        request.setMoney(tradeRequestDto.getMoney());
        //数据校验
        if(tradeRequestDto.getTradeIds().size() > maxSize){
            throw new RuntimeException("最多关联5条贸易记录");
        }
        //设置关联信息
        Integer firstIdOfCons = tradeRequestDto.getTradeIds().get(0);
        Trade trade = tradeMapper.selectById(firstIdOfCons);
        request.setLedger(trade.getLedgerId());
        request.setOurDept(trade.getOurDeptId());
        request.setCurrency(trade.getCurrencyId());
        request.setCompany(trade.getCompanyId());
        request.setOrderNo(trade.getOrderNo());
        //设置银行信息
        request.setBank(tradeRequestDto.getBank());
        //设置金额
        request.setAmount(tradeRequestDto.getAmount());
        request.setPaid(tradeRequestDto.getPaid());
        //设置申请单号,REQ+款项+款项明细+账套+部门+6日期+3序号
        StringBuilder sb = new StringBuilder();
        sb.append("REQ");
        sb.append(request.getMoney());
        sb.append(request.getType());
        sb.append(String.format("%02d", request.getLedger()));
        sb.append(String.format("%02d", request.getOurDept()));
        sb.append(request.getDate().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
        String prefix = sb.toString();
        String seqId = seqIdGenerator.generateAutoIncreaseSeqId(prefix, 3);
        request.setRequestNo(prefix + seqId);
        //设置其余属性
        request.setNote(tradeRequestDto.getNote());
        //同步对应的贸易记录的requestNo字段
        for (Integer tradeId : tradeRequestDto.getTradeIds()) {
            Trade trade1 = new Trade();
            trade1.setRequestNo(request.getRequestNo());
            trade1.setId(tradeId);
            tradeMapper.updateById(trade1);
        }
        requestMapper.insert(request);
    }

    @Override
    public void updateRequest(Request request) {
        requestMapper.updateById(request);
    }

    @Override
    public void deleteRequest(Integer id) {
        requestMapper.deleteById(id);
    }

    @Override
    public PageVo<StampDutyRequestVo> getPageForStampDuty(RequestPageDto pageDto) {
        //条件查询
        Page<Request> requestPage = getRequestPage(pageDto);
        List<Request> records = requestPage.getRecords();
        List<StampDutyRequestVo> result = new ArrayList<>();
        //转换为vo
        for (Request record : records) {
            StampDutyRequestVo stampDutyRequestVo = new StampDutyRequestVo();
            BeanUtils.copyProperties(record, stampDutyRequestVo);
            stampDutyRequestVo.setLedger(companyMapper.selectById(record.getLedger()).getShortname());
            stampDutyRequestVo.setOurDept(companydeptMapper.selectById(record.getOurDept()).getName());
            Bankinfo bank = bankinfoMapper.selectById(record.getBank());
            stampDutyRequestVo.setBankName(bank.getName());
            stampDutyRequestVo.setAccount(bank.getAccounts());
            stampDutyRequestVo.setCurrency(currencyMapper.selectById(record.getCurrency()).getName());
            result.add(stampDutyRequestVo);
        }
        return new PageVo<>(requestPage.getPages(), requestPage.getTotal(), result);
    }

    @Override
    public PageVo<TradeRequestVo> getPageForTrade(RequestPageDto pageDto) {
        //条件查询
        Page<Request> requestPage = getRequestPage(pageDto);
        List<Request> records = requestPage.getRecords();
        List<TradeRequestVo> result = new ArrayList<>();
        //转换为vo
        for (Request record : records) {
            TradeRequestVo tradeRequestVo = new TradeRequestVo();
            BeanUtils.copyProperties(record, tradeRequestVo);
            tradeRequestVo.setLedger(companyMapper.selectById(record.getLedger()).getShortname());
            tradeRequestVo.setOurDept(companydeptMapper.selectById(record.getOurDept()).getName());
            if (Objects.nonNull(record.getCompany())){
                tradeRequestVo.setCompany(companyMapper.selectById(record.getCompany()).getShortname());
            }
            Bankinfo bank = bankinfoMapper.selectById(record.getBank());
            tradeRequestVo.setBankName(bank.getName());
            tradeRequestVo.setAccount(bank.getAccounts());
            tradeRequestVo.setCurrency(currencyMapper.selectById(record.getCurrency()).getName());
            tradeRequestVo.setType(moneytypeMapper.selectById(record.getType()).getType());
            result.add(tradeRequestVo);
        }
        return new PageVo<>(requestPage.getPages(), requestPage.getTotal(), result);
    }

    @Override
    @Transactional
    public String uploadRequestImage(Integer requestId, MultipartFile multipartFile) {
        String url = fileOperationUtil.uploadImage(multipartFile);
        Request request = requestMapper.selectById(requestId);
        request.setScan(url);
        requestMapper.updateById(request);
        return url;
    }

    private Page<Request> getRequestPage(RequestPageDto pageDto) {
        //条件查询
        LambdaQueryWrapper<Request> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Objects.nonNull(pageDto.getDate()), Request::getDate, pageDto.getDate());
        queryWrapper.eq(Objects.nonNull(pageDto.getFinished()), Request::getFinished, pageDto.getFinished());
        queryWrapper.eq(Objects.nonNull(pageDto.getLedger()), Request::getLedger, pageDto.getLedger());
        queryWrapper.eq(Objects.nonNull(pageDto.getOurDept()), Request::getOurDept, pageDto.getOurDept());
        queryWrapper.eq(StringUtils.isNotBlank(pageDto.getTaxAuthority()), Request::getTaxAuthority, pageDto.getTaxAuthority());
        queryWrapper.eq(Objects.nonNull(pageDto.getCompany()), Request::getCompany, pageDto.getCompany());
        queryWrapper.likeRight(StringUtils.isNotBlank(pageDto.getRequestNo()), Request::getRequestNo, pageDto.getRequestNo());
        Page<Request> requestPage = requestMapper.selectPage(PageUtil.initPage(pageDto), queryWrapper);
        return requestPage;
    }

}
